#ifndef __UART4DATA_H__
#define __UART4DATA_H__

#include "BasicInclude.h"
#include "protol_machine.h"

#define UART4_BUF_SIZE	512

#define FRAME_DATALENGTH_DATAONLY	0		//表示通信帧中数据长度部分并非仅仅数据部分长度，而是整个数据包的长度
#define FRAME_HEADER	0x5E


#define LOGIN_REQUEST_CMD		0x00
#define LOGIN_RESPONS_CMD 	0x01
	
#define UPDATE_REQUEST_CMD	0x04
#define UPDATE_RESPONS_CMD	0x05
	


typedef enum __xpbms_cmd_set {
	eLoginRequestData,
	eLoginResponseData
}XPBMS_Cmd_Set;

typedef __packed struct
{
	uint8_t Header;
	uint8_t CommandNum;
	uint8_t PkgSerNum;
	uint16_t PckLength;
	uint8_t PckStatus;
	uint8_t CrcVal;
} XPBMSHeader;

#define DEV_RUN_POS_BOOT	0x00
#define DEV_RUN_POS_APP		0x01

//BMS登录请求数据部分数据结构
typedef __packed struct
{
	uint32_t ModelRandNum;			//设备登录随机数
	uint8_t ModelMCUID[12];			//设备的单片机ID 
} tMCUID;

typedef __packed struct
{
	uint8_t DevRunPos;					//设备运行在bootloader还是App
	uint8_t ModelSn[32];				//设备序列号
	uint8_t SoftVersion[3];			//软件版本号
	uint8_t HardVersion[3];			//硬件版本号
	uint8_t ModelPassword[8];		//设备登录密码
	tMCUID MCUID;								//设备MCUID
} XPBMS_LoginRequest_Data;


//BMS登录服务器回复数据部分数据结构
typedef __packed struct
{
	uint32_t DevCommID;					//设备在数据库中的ID，设备登录成功之后以该ID作为唯一身份标识进行通信
	uint16_t PackCapcity;				//电池包的设计容量。长度：2Byte
	uint8_t PackSerialCount;		//设备总串数
	uint8_t DevNeedUpdate;			//设备是否需要升级
	uint8_t DevCanWork;					//设备是否允许工作
	uint8_t MCUID[16];					//设备的单片机ID
} XPBMS_LoginResponse_Data;


typedef __packed struct
{
	XPBMSHeader Header;
	XPBMS_LoginRequest_Data Data;
} LoginRequestFrame;

typedef __packed struct
{
	XPBMSHeader Header;
	XPBMS_LoginResponse_Data Data;
} LoginResponseFrame;


//升级命令请求服务器
typedef __packed struct
{
	uint32_t DeviceID;
	uint8_t UpdateSubCmd;
	uint8_t UpdateData[8];
} XPBMS_UpdateRequest_Data;

typedef __packed struct
{
	XPBMSHeader Header;
	XPBMS_UpdateRequest_Data Data;
} UpdateRequestFrame;

//升级命令回复服务器
typedef __packed struct
{
	uint32_t DeviceID;
	uint8_t UpdateSubCmd;
	uint8_t UpdateData[];
} XPBMS_UpdateResponse_Data;

typedef __packed struct
{
	XPBMSHeader Header;
	XPBMS_UpdateResponse_Data Data;
} UpdateResponseFrame;

#if FRAME_DATALENGTH_DATAONLY == 0
	#define GET_FRAME_LENGTH(x)	(sizeof(x))
	#define GET_DATA_LENGTH(x)	(x-sizeof(XPBMSHeader)-sizeof(XPBMS_UpdateResponse_Data))
#else

#endif

ProtolMachine* InitUart4Data(void);
bool TryDeviceLogin(void);
bool RequestDevicePrepareUpdate(void);
#endif
